"""
旅游助手Agent核心类
集成RAG工具和高德地图工具，实现智能旅游助手功能
"""

import logging
from typing import Dict, List, Optional, Any, Tuple
from dataclasses import dataclass
from contextlib import asynccontextmanager

from ..retrieval.retrieval_tool import RetrievalTool
from ..tools.amap_navigation import AmapNavigationTool
from ..models.llm_config import LLMConfig
from ..utils.logger import setup_logger
from .intent_classifier import IntentClassifier, IntentType
from .quality_checker import QualityChecker, QualityLevel


@dataclass
class AgentResponse:
    """Agent响应数据类"""
    content: str
    intent: IntentType
    tool_used: str
    quality_score: float
    needs_clarification: bool
    clarification_message: Optional[str] = None


class TravelAgent:
    """旅游助手Agent"""
    
    def __init__(self, retrieval_tool: RetrievalTool, navigation_tool: AmapNavigationTool):
        """
        初始化旅游助手Agent
        
        Args:
            retrieval_tool: RAG检索工具
            navigation_tool: 高德地图导航工具
        """
        self.logger = setup_logger(__name__)
        
        # 工具初始化
        self.retrieval_tool = retrieval_tool
        self.navigation_tool = navigation_tool
        
        # 组件初始化
        self.intent_classifier = IntentClassifier()
        self.quality_checker = QualityChecker()
        
        # 对话上下文
        self.conversation_context = {
            'last_destination': None,
            'last_origin': None,
            'last_intent': None,
            'conversation_history': []
        }
        
        self.logger.info("旅游助手Agent初始化完成")
    
    def process_query(self, query: str, user_id: str = "default") -> AgentResponse:
        """
        处理用户查询
        
        Args:
            query: 用户查询文本
            user_id: 用户ID
            
        Returns:
            Agent响应
        """
        try:
            self.logger.info(f"开始处理查询: {query}")
            
            # 更新对话上下文
            self._update_conversation_context(query)
            
            # 意图识别
            intent_result = self.intent_classifier.classify_intent(query)
            
            # 检查是否是路线规划的补充信息
            if (intent_result.intent == IntentType.ROUTE_PLANNING and 
                self.conversation_context.get('last_intent') == IntentType.ROUTE_PLANNING and
                self.conversation_context.get('needs_clarification', False)):
                # 这是对之前路线规划请求的补充
                self.logger.info("检测到路线规划补充信息")
                response = self._handle_route_planning_followup(query, intent_result)
            else:
                # 根据意图调用相应工具
                if intent_result.intent == IntentType.TRAVEL_CONSULTATION:
                    response = self._handle_travel_consultation(query, intent_result)
                elif intent_result.intent == IntentType.ROUTE_PLANNING:
                    response = self._handle_route_planning(query, intent_result)
                else:
                    response = self._handle_unknown_intent(query, intent_result)
            
            # 质量检查
            quality_result = self.quality_checker.check_quality(query, response.content)
            
            # 如果质量太差，返回拒绝消息
            if self.quality_checker.should_reject_answer(quality_result):
                response.content = self.quality_checker.get_rejection_message(quality_result)
                response.quality_score = 0.0
            
            # 更新响应质量信息
            response.quality_score = quality_result.score
            
            # 更新对话上下文
            self.conversation_context['last_intent'] = intent_result.intent
            self.conversation_context['needs_clarification'] = response.needs_clarification
            
            self.logger.info(f"查询处理完成: 意图={intent_result.intent.value}, 质量={quality_result.level.value}")
            return response
            
        except Exception as e:
            self.logger.error(f"处理查询失败: {e}")
            return AgentResponse(
                content=f"抱歉，处理您的请求时出现错误: {str(e)}",
                intent=IntentType.UNKNOWN,
                tool_used="error_handler",
                quality_score=0.0,
                needs_clarification=False
            )
    
    def _handle_travel_consultation(self, query: str, intent_result) -> AgentResponse:
        """处理旅游咨询请求"""
        try:
            self.logger.info("处理旅游咨询请求")
            
            # 使用RAG工具生成答案
            answer = self.retrieval_tool.generate_answer(query)
            
            return AgentResponse(
                content=answer,
                intent=IntentType.TRAVEL_CONSULTATION,
                tool_used="rag_retrieval",
                quality_score=0.0,  # 将在后续质量检查中更新
                needs_clarification=False
            )
            
        except Exception as e:
            self.logger.error(f"旅游咨询处理失败: {e}")
            return AgentResponse(
                content=f"抱歉，无法为您提供旅游咨询: {str(e)}",
                intent=IntentType.TRAVEL_CONSULTATION,
                tool_used="rag_retrieval",
                quality_score=0.0,
                needs_clarification=False
            )
    
    def _handle_route_planning(self, query: str, intent_result) -> AgentResponse:
        """处理路线规划请求"""
        try:
            self.logger.info("处理路线规划请求")
            
            # 提取参数
            params = intent_result.extracted_params
            
            # 智能参数补全
            origin, destination, transport_mode = self._complete_route_parameters(
                query, params
            )
            
            # 检查参数完整性
            if not origin or not destination:
                missing_params = self.intent_classifier.get_missing_parameters(query, IntentType.ROUTE_PLANNING)
                clarification_message = self.intent_classifier.suggest_clarification(query, IntentType.ROUTE_PLANNING)
                
                return AgentResponse(
                    content=clarification_message,
                    intent=IntentType.ROUTE_PLANNING,
                    tool_used="parameter_extraction",
                    quality_score=0.0,
                    needs_clarification=True,
                    clarification_message=clarification_message
                )
            
            # 智能选择出行方式
            if not transport_mode:
                transport_mode = self._recommend_transport_mode(origin, destination)
            
            # 调用高德地图工具
            route_info = self.navigation_tool.plan_route(
                origin=origin,
                destination=destination,
                mode=transport_mode
            )
            
            # 格式化路线信息
            formatted_route = self.navigation_tool.format_route_info(route_info)
            
            # 构建响应
            response_content = f"为您规划从 {origin} 到 {destination} 的路线：\n\n{formatted_route}"
            
            return AgentResponse(
                content=response_content,
                intent=IntentType.ROUTE_PLANNING,
                tool_used="amap_navigation",
                quality_score=0.0,  # 将在后续质量检查中更新
                needs_clarification=False
            )
            
        except Exception as e:
            self.logger.error(f"路线规划处理失败: {e}")
            return AgentResponse(
                content=f"抱歉，无法为您规划路线: {str(e)}",
                intent=IntentType.ROUTE_PLANNING,
                tool_used="amap_navigation",
                quality_score=0.0,
                needs_clarification=False
            )
    
    def _handle_route_planning_followup(self, query: str, intent_result) -> AgentResponse:
        """处理路线规划的补充信息"""
        try:
            self.logger.info("处理路线规划补充信息")
            
            # 提取参数
            params = intent_result.extracted_params
            
            # 智能参数补全
            origin, destination, transport_mode = self._complete_route_parameters(
                query, params
            )
            
            # 检查参数完整性
            if not origin or not destination:
                # 如果仍然缺少参数，继续询问
                missing_params = self.intent_classifier.get_missing_parameters(query, IntentType.ROUTE_PLANNING)
                clarification_message = self.intent_classifier.suggest_clarification(query, IntentType.ROUTE_PLANNING)
                
                return AgentResponse(
                    content=clarification_message,
                    intent=IntentType.ROUTE_PLANNING,
                    tool_used="parameter_extraction",
                    quality_score=0.0,
                    needs_clarification=True,
                    clarification_message=clarification_message
                )
            
            # 智能选择出行方式
            if not transport_mode:
                transport_mode = self._recommend_transport_mode(origin, destination)
            
            # 调用高德地图工具
            route_info = self.navigation_tool.plan_route(
                origin=origin,
                destination=destination,
                mode=transport_mode
            )
            
            # 格式化路线信息
            formatted_route = self.navigation_tool.format_route_info(route_info)
            
            # 构建响应
            response_content = f"为您规划从 {origin} 到 {destination} 的路线：\n\n{formatted_route}"
            
            return AgentResponse(
                content=response_content,
                intent=IntentType.ROUTE_PLANNING,
                tool_used="amap_navigation",
                quality_score=0.0,  # 将在后续质量检查中更新
                needs_clarification=False
            )
            
        except Exception as e:
            self.logger.error(f"路线规划补充信息处理失败: {e}")
            return AgentResponse(
                content=f"抱歉，无法为您规划路线: {str(e)}",
                intent=IntentType.ROUTE_PLANNING,
                tool_used="amap_navigation",
                quality_score=0.0,
                needs_clarification=False
            )
    
    def _handle_unknown_intent(self, query: str, intent_result) -> AgentResponse:
        """处理未知意图"""
        self.logger.info("处理未知意图")
        
        return AgentResponse(
            content="抱歉，我没有理解您的需求。请告诉我您是想了解旅游信息还是需要路线规划？",
            intent=IntentType.UNKNOWN,
            tool_used="intent_classification",
            quality_score=0.0,
            needs_clarification=True,
            clarification_message="请明确您的需求类型"
        )
    
    def _complete_route_parameters(self, query: str, params: Dict[str, str]) -> Tuple[Optional[str], Optional[str], Optional[str]]:
        """智能补全路线规划参数"""
        origin = params.get('origin')
        destination = params.get('destination')
        transport_mode = params.get('transport_mode')
        
        # 使用上下文信息补全参数
        if not origin and self.conversation_context['last_origin']:
            origin = self.conversation_context['last_origin']
        
        if not destination and self.conversation_context['last_destination']:
            destination = self.conversation_context['last_destination']
        
        # 如果仍然缺少目的地，尝试从对话历史中提取
        if not destination and self.conversation_context.get('conversation_history'):
            # 从最近的对话中查找目的地信息
            for hist_query in reversed(self.conversation_context['conversation_history'][-3:]):
                # 查找包含"去"、"到"等关键词的查询
                if any(keyword in hist_query for keyword in ['去', '到', '怎么走', '怎么去']):
                    # 尝试提取目的地
                    hist_params = self.intent_classifier._extract_parameters(hist_query)
                    if hist_params.get('destination'):
                        destination = hist_params['destination']
                        break
        
        # 更新上下文
        if origin:
            self.conversation_context['last_origin'] = origin
        if destination:
            self.conversation_context['last_destination'] = destination
        
        return origin, destination, transport_mode
    
    def _recommend_transport_mode(self, origin: str, destination: str) -> str:
        """智能推荐出行方式"""
        try:
            # 获取所有出行方式的路线摘要
            summary = self.navigation_tool.get_route_summary(origin, destination)
            
            # 检查summary是否为字典类型
            if not isinstance(summary, dict):
                self.logger.warning(f"路线摘要格式不正确: {type(summary)}")
                return "transit"  # 默认公共交通
            
            # 根据距离和时间推荐最佳方式
            best_mode = "walking"  # 默认步行
            
            if "walking" in summary and "error" not in summary["walking"]:
                walking_distance = self._parse_distance(summary["walking"]["distance"])
                if walking_distance < 2000:  # 2公里内推荐步行
                    return "walking"
            
            if "cycling" in summary and "error" not in summary["cycling"]:
                cycling_distance = self._parse_distance(summary["cycling"]["distance"])
                if cycling_distance < 10000:  # 10公里内推荐骑行
                    return "cycling"
            
            if "transit" in summary and "error" not in summary["transit"]:
                return "transit"  # 公共交通通常是最佳选择
            
            return "driving"  # 最后选择驾车
            
        except Exception as e:
            self.logger.warning(f"推荐出行方式失败: {e}")
            return "transit"  # 默认公共交通
    
    def _parse_distance(self, distance_str: str) -> float:
        """解析距离字符串为米"""
        try:
            if "公里" in distance_str:
                km = float(distance_str.replace("公里", "").strip())
                return km * 1000
            elif "米" in distance_str:
                return float(distance_str.replace("米", "").strip())
            else:
                return 0.0
        except:
            return 0.0
    
    def _update_conversation_context(self, query: str):
        """更新对话上下文"""
        # 添加到对话历史
        self.conversation_context['conversation_history'].append(query)
        
        # 保持历史记录在合理范围内
        if len(self.conversation_context['conversation_history']) > 10:
            self.conversation_context['conversation_history'] = \
                self.conversation_context['conversation_history'][-10:]
    
    def get_conversation_summary(self) -> Dict[str, Any]:
        """获取对话摘要"""
        return {
            'last_destination': self.conversation_context['last_destination'],
            'last_origin': self.conversation_context['last_origin'],
            'last_intent': self.conversation_context['last_intent'],
            'conversation_count': len(self.conversation_context['conversation_history'])
        }
    
    def reset_conversation(self):
        """重置对话上下文"""
        self.conversation_context = {
            'last_destination': None,
            'last_origin': None,
            'last_intent': None,
            'conversation_history': []
        }
        self.logger.info("对话上下文已重置")
    
    def get_agent_status(self) -> Dict[str, Any]:
        """获取Agent状态"""
        return {
            'retrieval_tool_available': self.retrieval_tool is not None,
            'navigation_tool_available': self.navigation_tool is not None,
            'intent_classifier_available': self.intent_classifier is not None,
            'quality_checker_available': self.quality_checker is not None,
            'conversation_context': self.get_conversation_summary()
        }
